package com.mxpio.erp.equipment.service.impl;

import cn.hutool.json.JSONUtil;
import com.mxpio.erp.common.enums.CommonEnums;
import com.mxpio.erp.common.enums.OrderEnums;
import com.mxpio.erp.common.equipment.entity.*;
import com.mxpio.erp.common.equipment.service.EquipmentAreaService;
import com.mxpio.erp.common.equipment.service.EquipmentCalibrationService;
import com.mxpio.erp.common.equipment.service.EquipmentEqpBasicsService;
import com.mxpio.erp.common.equipment.service.EquipmentEqpStatusRecordsService;
import com.mxpio.erp.common.inventory.entity.InvFlow;
import com.mxpio.erp.common.technology.entity.Item;
import com.mxpio.erp.common.vo.InvFlowSummaryVo;
import com.mxpioframework.common.exception.MBootException;
import com.mxpioframework.common.util.BeanReflectionUtils;
import com.mxpioframework.common.vo.Result;
import com.mxpioframework.jpa.JpaUtil;
import com.mxpioframework.jpa.policy.impl.CrudType;
import com.mxpioframework.system.service.DictCacheService;
import com.mxpioframework.system.service.DictService;
import com.mxpioframework.system.service.impl.BaseServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * 设备台账Service业务层处理
 *
 * @author Cheng
 * @date 2023-07-01
 */
@Service
@Slf4j
public class EquipmentEqpBasicsServiceImpl extends BaseServiceImpl<EquipmentEqpBasics> implements EquipmentEqpBasicsService {

    @Resource
    private EquipmentAreaService equipmentAreaService;

    @Resource
    private EquipmentEqpStatusRecordsService eqpStatusRecordsService;

    private DictCacheService cacheService;

    private DictService dictService;

    @Autowired
    private EquipmentCalibrationService calibrationService;

    @Override
    @Transactional(readOnly = false)
    public void saveEqp(EquipmentEqpBasics equipmentEqpBasics) {
        //EquipmentArea area = JpaUtil.getOne(EquipmentArea.class, equipmentEqpBasics.getAreaId());
        //equipmentEqpBasics.setAreaName(equipmentAreaService.getParentAllNameByPid(area.getPid()) + "/" + area.getAreaName());
        equipmentEqpBasics.setIsDel(0);
        this.save(equipmentEqpBasics);
        if (CrudType.SAVE.equals(equipmentEqpBasics.getCrudType())){
            List<EquipmentEqpBom> eqpBomList = JpaUtil.linq(EquipmentEqpBom.class).equal("basicsCode", equipmentEqpBasics.getBasicsCode()).list();
            if (eqpBomList.size()==0){//没有值
                String eqpCode = equipmentEqpBasics.getEqpCode();
                List<EquipmentBom> bomList = JpaUtil.linq(EquipmentBom.class).equal("eqpCode", eqpCode).list();
                if (bomList.size()>0){
                    for (EquipmentBom bom:bomList){
                        EquipmentEqpBom equipmentEqpBom = new EquipmentEqpBom();
                        BeanReflectionUtils.copyProperties(equipmentEqpBom,bom);
                        equipmentEqpBom.setBasicsCode(equipmentEqpBasics.getBasicsCode());
                        equipmentEqpBom.setId(null);
                        JpaUtil.save(equipmentEqpBom);//保存到设备台账 备件bom中
                    }
                }
            }
            List<EquipmentEqpAttr> eqpAttrList = JpaUtil.linq(EquipmentEqpAttr.class).equal("basicsCode", equipmentEqpBasics.getBasicsCode()).list();
            if (eqpAttrList.size()==0){//没有值
                String eqpCode = equipmentEqpBasics.getEqpCode();
                List<EquipmentAttr> attrList = JpaUtil.linq(EquipmentAttr.class).equal("eqpCode", eqpCode).list();
                if (attrList.size()>0){
                    for (EquipmentAttr attr:attrList){
                        EquipmentEqpAttr eqpAttr = new EquipmentEqpAttr();
                        BeanReflectionUtils.copyProperties(eqpAttr,attr);
                        eqpAttr.setBasicsCode(equipmentEqpBasics.getBasicsCode());
                        eqpAttr.setId(null);
                        eqpAttr.setIsSync(CommonEnums.YesNo.YES.getCode());//档案信息由设备同步而来
                        JpaUtil.save(eqpAttr);//保存到设备台账 档案
                    }
                }
            }
        }


        //设置设备分类中间表
        String eqpTypeId = equipmentEqpBasics.getEqpTypeId();
        List<String> arr = Arrays.asList(eqpTypeId.split(","));
        for (String s : arr) {
            EquipmentEqpRelCategory bean = new EquipmentEqpRelCategory();
            bean.setBasicsCode(equipmentEqpBasics.getBasicsCode());
            bean.setCategoryId(s);
            JpaUtil.save(bean);
        }

        //添加设备状态记录
        EquipmentEqpStatusRecords records = new EquipmentEqpStatusRecords();
        records.setBasicsCode(equipmentEqpBasics.getBasicsCode());
        records.setIsDel(0);
        records.setNowStatus(equipmentEqpBasics.getStatus());
        records.setReason("添加设备-状态变更");
        JpaUtil.save(records);
    }

    @Override
    @Transactional(readOnly = false)
    public void updateEqpById(EquipmentEqpBasics equipmentEqpBasics) {
        //EquipmentArea area = JpaUtil.getOne(EquipmentArea.class, equipmentEqpBasics.getAreaId());
        //equipmentEqpBasics.setAreaName(equipmentAreaService.getParentAllNameByPid(area.getPid()) + "/" + area.getAreaName());

        JpaUtil.lind(EquipmentEqpRelCategory.class).equal("basicsCode", equipmentEqpBasics.getBasicsCode()).delete();

        //设置设备分类中间表
        String eqpTypeId = equipmentEqpBasics.getEqpTypeId();
        List<String> arr = Arrays.asList(eqpTypeId.split(","));
        for (String s : arr) {
            EquipmentEqpRelCategory bean = new EquipmentEqpRelCategory();
            bean.setBasicsCode(equipmentEqpBasics.getBasicsCode());
            bean.setCategoryId(s);
            JpaUtil.save(bean);
        }
        EquipmentEqpBasics bean = this.getById(EquipmentEqpBasics.class, equipmentEqpBasics.getBasicsCode());

        if (!bean.getEqpName().equals(equipmentEqpBasics.getEqpName())){
            //当设备名称修改时，修改设备状态记录
            //添加设备状态记录
            EquipmentEqpStatusRecords records = new EquipmentEqpStatusRecords();
            records.setBasicsCode(bean.getBasicsCode());
            records.setBasicsCode(equipmentEqpBasics.getBasicsCode());
            records.setReason("修改设备-设备名称变更");
            records.setBeforeStatus(bean.getStatus());
            records.setNowStatus(equipmentEqpBasics.getStatus());
            JpaUtil.save(records);
        }

        if (bean.getStatus() != equipmentEqpBasics.getStatus()) {
            //更新上一条记录的下一个操作时间
            eqpStatusRecordsService.saveRecordAndUpdatePreRecord(bean, equipmentEqpBasics.getStatus(), "修改设备-状态变更");
        }
        this.update(equipmentEqpBasics);
    }

    @Override
    @Transactional
    public void bindNFC(EquipmentEqpBasics equipmentEqpBasics) {
        EquipmentEqpBasics basics = this.getById(EquipmentEqpBasics.class, equipmentEqpBasics.getBasicsCode());
        if (null == basics) {
            throw new MBootException("未找到对应设备");
        }
        //清空该NFC之前绑定
        JpaUtil.linu(EquipmentEqpBasics.class).set("nfcNumber", null).equal("nfcNumber", equipmentEqpBasics.getNfcNumber()).update();
        basics.setNfcNumber(equipmentEqpBasics.getNfcNumber());
        this.update(basics);
    }

    @Override
    public String bindNFCList(String listStr) {
        List<EquipmentEqpBasics> list = JSONUtil.toList(JSONUtil.parseArray(listStr), EquipmentEqpBasics.class);
        int errorNum= 0;
        ArrayList ids = new ArrayList<>();
        for (EquipmentEqpBasics tpmEqpBasics : list) {
            try{
                if (tpmEqpBasics ==null || StringUtils.isBlank(tpmEqpBasics.getBasicsCode())){
                    throw new MBootException("上传设备id或者实体不存在！");
                }
                this.bindNFC(tpmEqpBasics);
                ids.add(tpmEqpBasics.getBasicsCode());
            }catch (Exception e){
                errorNum++;
                log.error("设备ID："+tpmEqpBasics.getBasicsCode()+"，绑定NFC失败");
                e.printStackTrace();
            }
        }

        if (errorNum>0){
            return  JSONUtil.toJsonStr(ids);
        }
        return null;
    }

    @Override
    @Transactional
    public Result<Collection<InvFlowSummaryVo>> getPickBomList(String basicsCode) {
        Map<String,Item> itemMap = new HashMap<>();
        Map<String, InvFlowSummaryVo> summaryMap = new HashMap<>();
        //先查询 维修
        List<EquipmentRepairPickupLine> repairPickupLines = JpaUtil.linq(EquipmentRepairPickupLine.class)
                .exists(EquipmentRepair.class)
                    .equalProperty("bizNo", "bizNo")
                    .equal("targetId", basicsCode)
                .end()
                .list();
        if (repairPickupLines.size()>0){
            for (EquipmentRepairPickupLine repairPickupLine:repairPickupLines){
                String itemCode = repairPickupLine.getItemCode();
                String bizNo = repairPickupLine.getBizNo();
                String lineNo = repairPickupLine.getLineNo();

                Item item = null;
                if (itemMap.containsKey(itemCode)){
                    item=itemMap.get(itemCode);
                }else{
                    item = JpaUtil.getOne(Item.class, itemCode);
                    itemMap.put(itemCode,item);
                }
                if (item==null){
                    log.error("物料编码"+itemCode+"在物料基础信息中不存在！");
                    continue;
                }
                List<InvFlow> flowList = JpaUtil.linq(InvFlow.class)
                        .equal("originBizNo", bizNo)
                        .equal("originBizLineNo", lineNo).list();
                if (flowList.size()>0){
                    for (InvFlow flow:flowList){
                        String key = flow.getItemCode();
                        InvFlowSummaryVo vo = summaryMap.get(key);
                        if(vo==null){
                            vo = new InvFlowSummaryVo();
                            vo.setItemCode(item.getItemCode());
                            vo.setItemName(item.getItemName());
                            vo.setItemSpec(item.getItemSpec());
                            vo.setDrawingNo(item.getDrawingNo());
                            vo.setUnitCode(item.getUnitCode());
                            vo.setQuantity(BigDecimal.ZERO);
                        }
                        if (OrderEnums.AccessType.OUT.getCode().equals(flow.getAccessType())){
                            vo.setQuantity(vo.getQuantity().add(flow.getQuantity()));
                        }else{
                            vo.setQuantity(vo.getQuantity().subtract(flow.getQuantity()));
                        }
                        summaryMap.put(key, vo);
                    }
                }
            }
        }

        //再查询 保养
        List<EquipmentUpkeepTaskPickupLine> upkeepTaskPickupLines = JpaUtil.linq(EquipmentUpkeepTaskPickupLine.class)
                .exists(EquipmentUpkeepTask.class)
                .equalProperty("bizNo", "bizNo")
                .equal("targetId", basicsCode)
                .end()
                .list();
        if (upkeepTaskPickupLines.size()>0){
            for (EquipmentUpkeepTaskPickupLine upkeepTaskPickupLine:upkeepTaskPickupLines){
                String itemCode = upkeepTaskPickupLine.getItemCode();
                String bizNo = upkeepTaskPickupLine.getBizNo();
                String lineNo = upkeepTaskPickupLine.getLineNo();

                Item item = null;
                if (itemMap.containsKey(itemCode)){
                    item=itemMap.get(itemCode);
                }else{
                    item = JpaUtil.getOne(Item.class, itemCode);
                    itemMap.put(itemCode,item);
                }
                if (item==null){
                    log.error("物料编码"+itemCode+"在物料基础信息中不存在！");
                    continue;
                }
                List<InvFlow> flowList = JpaUtil.linq(InvFlow.class)
                        .equal("originBizNo", bizNo)
                        .equal("originBizLineNo", lineNo).list();
                if (flowList.size()>0){
                    for (InvFlow flow:flowList){
                        String key = flow.getItemCode();
                        InvFlowSummaryVo vo = summaryMap.get(key);
                        if(vo==null){
                            vo = new InvFlowSummaryVo();
                            vo.setItemCode(item.getItemCode());
                            vo.setItemName(item.getItemName());
                            vo.setItemSpec(item.getItemSpec());
                            vo.setDrawingNo(item.getDrawingNo());
                            vo.setUnitCode(item.getUnitCode());
                            vo.setQuantity(BigDecimal.ZERO);
                        }
                        if (OrderEnums.AccessType.OUT.getCode().equals(flow.getAccessType())){
                            vo.setQuantity(vo.getQuantity().add(flow.getQuantity()));
                        }else{
                            vo.setQuantity(vo.getQuantity().subtract(flow.getQuantity()));
                        }
                        summaryMap.put(key, vo);
                    }
                }
            }
        }
        for (String key:summaryMap.keySet()){
            InvFlowSummaryVo vo = summaryMap.get(key);
            if(BigDecimal.ZERO.compareTo(vo.getQuantity()) == 0){
                summaryMap.remove(key);
            }
        }
        return Result.OK(summaryMap.values());
    }

    @Override
    @Transactional
    public void updateLastTime(EquipmentEqpBasics equipmentEqpBasics, String calCode) {
        EquipmentEqpBasics eqpBasics = this.getById(EquipmentEqpBasics.class, equipmentEqpBasics.getBasicsCode());
        EquipmentCalibration calibration = calibrationService.getById(EquipmentCalibration.class,calCode);
        eqpBasics.setLastCalibrateDate(calibration.getActualEndDate());
        this.update(eqpBasics);
    }
}
